package com.yangit.temp.util.minio.controller;

import io.minio.ObjectStat;
import io.swagger.annotations.ApiOperation;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.util.AntPathMatcher;

import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.HandlerMapping;

import com.yangit.temp.common.entity.result.JsonResult;
import com.yangit.temp.common.util.string.StringUtils;
import com.yangit.temp.util.minio.entity.MinioTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;

/**
 * minio上传,下载,删除接口
 */
@RestController
@RequestMapping("/minio")
@Slf4j
public class MinioController {

	@Autowired
	private MinioTemplate minioTemplate;

	/**
	 * -下载文件
	 * http://172.16.101.87:8090/minio/download?fileName=1103111625a0f59f9afb32be51.jpg&bucketName=test
	 */
	@ApiOperation(value = "下载文件")
	@GetMapping(value = "/download")
	@SneakyThrows(Exception.class)
	public void download(@RequestParam("fileName") String fileName, String bucketName, HttpServletResponse response) {
		ObjectStat stat = minioTemplate.statObject(bucketName, fileName);
		response.setContentType(stat.contentType());
		response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
		InputStream in = minioTemplate.getObject(bucketName, fileName);
		IOUtils.copy(in, response.getOutputStream());
		in.close();
	}

	/**
	 * -上传文件
	 * 
	 * @param file
	 * @return
	 * @throws Exception Exception
	 */
	@ApiOperation(value = "上传文件")
	@PostMapping(value = "/upload")
	@SneakyThrows(Exception.class)
	public JsonResult upload(@RequestParam("file") MultipartFile file, String bucketName) throws Exception {
		if (file.isEmpty()) {
			return JsonResult.error("上传文件不能为空");
		} else {
			// 得到文件流
			final InputStream is = file.getInputStream();
			// 文件名
			final String fileName = file.getOriginalFilename();
			// 把文件放到minio的boots桶里面
			minioTemplate.putObject("", fileName, is, -1);
			String objectUrl = minioTemplate.getObjectURL(bucketName, fileName);
			// 关闭输入流
			is.close();
			return JsonResult.ok(objectUrl);
		}
	}
	
	/**
	 * -上传文件
	 * 
	 * @param file
	 * @return
	 * @throws Exception Exception
	 */
	@ApiOperation(value = "上传文件,放入指定文件夹")
	@PostMapping(value = "/uploadPath")
	@SneakyThrows(Exception.class)
	public JsonResult uploadPath(@RequestParam("file") MultipartFile file, String bucketName,String targetPath) throws Exception {
		if (file.isEmpty()) {
			return JsonResult.error("上传文件不能为空");
		} else {
			// 得到文件流
			final InputStream is = file.getInputStream();
			// 文件名
			final String fileName = file.getOriginalFilename();
			// 把文件放到minio的boots桶里面
			minioTemplate.createImgPath(bucketName, (targetPath + "/" + fileName), is);
			// 关闭输入流
			is.close();
			return JsonResult.ok("");
		}
	}

	/**
	 * -删除文件
	 * 
	 * @param fileName
	 * @return JsonResult
	 */
	@ApiOperation(value = "删除文件")
	@GetMapping(value = "/delete", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
	@SneakyThrows(Exception.class)
	public JsonResult delete(@RequestParam("fileName") String fileName, String bucketName) {
		minioTemplate.removeObject("", fileName);
		return JsonResult.ok("删除成功");
	}

	/**
	 * -预览图片
	 * -请求地址：http://localhost:8090/minio/view/test/1103111625a0f59f9afb32be51.jpg
	 *
	 * @param request
	 * @param response
	 */
	@GetMapping(value = "/view/**")
	public void minioView(HttpServletRequest request, HttpServletResponse response) {
		// ISO-8859-1 ==> UTF-8 进行编码转换
		String imgPath = extractPathFromPattern(request);
		// 其余处理略
		InputStream inputStream = null;
		OutputStream outputStream = null;
		try {
			String bucketName = "";
			String fileName = "";
			response.setContentType("image/jpeg;charset=utf-8");
			if (StringUtils.isNotEmpty(imgPath)) {
				String[] split = imgPath.split("/");
				bucketName = split[0];
				fileName = split[1];
			}
			inputStream = minioTemplate.getObject(bucketName, fileName);
			;
			outputStream = response.getOutputStream();
			byte[] buf = new byte[1024];
			int len;
			while ((len = inputStream.read(buf)) > 0) {
				outputStream.write(buf, 0, len);
			}
			response.flushBuffer();
		} catch (IOException e) {
			log.error("预览图片失败" + e.getMessage());
			// e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					log.error(e.getMessage(), e);
				}
			}
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					log.error(e.getMessage(), e);
				}
			}
		}

	}

	/**
	 * -预览图片
	 * -请求地址：http://localhost:8090/minio/view/test/1103111625a0f59f9afb32be51.jpg
	 *
	 * @param request
	 * @param response
	 */
	@GetMapping(value = "/see/{bucketName}/{imgPath}/{fileName}")
	public void imageView(@PathVariable String bucketName, @PathVariable String imgPath, @PathVariable String fileName,
			HttpServletRequest request, HttpServletResponse response) {
		log.debug(imgPath);
		// 其余处理略
		InputStream inputStream = null;
		OutputStream outputStream = null;
		try {
			response.setContentType("image/jpeg;charset=utf-8");
			if (StringUtils.isNotBlank(imgPath)) {
				fileName = imgPath + "/" + fileName;
			}
			inputStream = minioTemplate.getObject(bucketName, fileName);
			;
			outputStream = response.getOutputStream();
			byte[] buf = new byte[1024];
			int len;
			while ((len = inputStream.read(buf)) > 0) {
				outputStream.write(buf, 0, len);
			}
			response.flushBuffer();
		} catch (IOException e) {
			log.error("预览图片失败" + e.getMessage());
			// e.printStackTrace();
		} finally {
			if (inputStream != null) {
				try {
					inputStream.close();
				} catch (IOException e) {
					log.error(e.getMessage(), e);
				}
			}
			if (outputStream != null) {
				try {
					outputStream.close();
				} catch (IOException e) {
					log.error(e.getMessage(), e);
				}
			}
		}

	}

	/**
	 * 把指定URL后的字符串全部截断当成参数 这么做是为了防止URL中包含中文或者特殊字符（/等）时，匹配不了的问题
	 * 
	 * @param request
	 * @return
	 */
	private static String extractPathFromPattern(final HttpServletRequest request) {
		String path = (String) request.getAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE);
		String bestMatchPattern = (String) request.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
		return new AntPathMatcher().extractPathWithinPattern(bestMatchPattern, path);
	}

}